/**
 * Created by ${PRODUCT_NAME}.
 * User: skylerparr
 * Date: 1/31/11
 * Time: 9:27 AM
 * To change this template use File | Settings | File Templates.
 */
package com.thoughtorigin.display.containers {
import flash.display.Sprite;

import org.flexunit.asserts.assertEquals;
import org.flexunit.asserts.assertFalse;
import org.flexunit.asserts.assertNotNull;
import org.flexunit.asserts.assertNull;
import org.flexunit.asserts.assertTrue;
import org.flexunit.async.Async;
import org.mockito.integrations.flexunit4.MockitoClassRunner;

[RunWith("org.mockito.integrations.flexunit4.MockitoClassRunner")]
public class ContainerTest {

    private var _container: Container;

    [Before]
    public function setUp(): void {
        _container = new Container();
    }

    [After]
    public function tearDown(): void {
        _container = null;
    }

    [Test]
    public function shouldAddChildToInnerContainer(): void {
        var child: Sprite = new Sprite();
        _container.addChild(child);

        assertEquals(child, _container.rawChildContainer.getChildAt(0));
    }

    [Test]
    public function shouldAddChildAtIndexOnInnerContainer(): void {
        var child: Sprite = new Sprite();
        var child1: Sprite = new Sprite();
        var child2: Sprite = new Sprite();

        _container.addChildAt(child2, 0);
        _container.addChildAt(child1, 0);
        _container.addChildAt(child, 0);

        assertEquals(child2, _container.getChildAt(2));
        assertEquals(child2, _container.rawChildContainer.getChildAt(2));
    }

    [Test]
    public function shouldRemoveChildFromInnerContainer(): void {
        var child: Sprite = new Sprite();
        var child1: Sprite = new Sprite();
        var child2: Sprite = new Sprite();

        _container.addChildAt(child2, 0);
        _container.addChildAt(child1, 0);
        _container.addChildAt(child, 0);

        assertEquals(3, _container.rawChildContainer.numChildren);
        assertEquals(child, _container.removeChild(child));
        assertEquals(2, _container.rawChildContainer.numChildren);
    }

    [Test]
    public function shouldRemovedChildAtFromInnerContainer(): void {
        var child: Sprite = new Sprite();
        var child1: Sprite = new Sprite();
        var child2: Sprite = new Sprite();

        _container.addChildAt(child2, 0);
        _container.addChildAt(child1, 1);
        _container.addChildAt(child, 2);

        assertEquals(3, _container.rawChildContainer.numChildren);
        assertEquals(child2, _container.removeChildAt(0));
        assertEquals(2, _container.rawChildContainer.numChildren);
    }

    [Test]
    public function shouldGetNumchildrenFromRawChildren(): void {
        var child: Sprite = new Sprite();
        var child1: Sprite = new Sprite();
        var child2: Sprite = new Sprite();

        _container.addChildAt(child2, 0);
        _container.addChildAt(child1, 1);
        _container.addChildAt(child, 2);

        assertEquals(3, _container.rawChildContainer.numChildren);
        assertEquals(3, _container.numChildren);
    }

    [Test]
    public function shouldGetChildIndexFromRawChildren(): void {
        var child: Sprite = new Sprite();
        var child1: Sprite = new Sprite();
        var child2: Sprite = new Sprite();

        _container.addChildAt(child2, 0);
        _container.addChildAt(child1, 1);
        _container.addChildAt(child, 2);

        assertEquals(1, _container.getChildIndex(child1));
    }

    [Test]
    public function shouldSetChildIndexFromRawChildren(): void {
        var child: Sprite = new Sprite();
        var child1: Sprite = new Sprite();
        var child2: Sprite = new Sprite();

        _container.addChildAt(child2, 0);
        _container.addChildAt(child1, 1);
        _container.addChildAt(child, 2);

        _container.setChildIndex(child, 0);

        assertEquals(child, _container.rawChildContainer.getChildAt(0));
    }

    [Test]
    public function shouldGetChildByNameFromRawChildren(): void {
        var child: Sprite = new Sprite();
        var child1: Sprite = new Sprite();
        var child2: Sprite = new Sprite();

        _container.addChildAt(child2, 0);
        _container.addChildAt(child1, 1);
        _container.addChildAt(child, 2);

        child.name = "1";
        child1.name = "2";
        child2.name = "3";

        assertEquals(child1, _container.getChildByName("2"));
        assertEquals(child2, _container.getChildByName("3"));
        assertEquals(child, _container.getChildByName("1"));
    }

    [Test]
    public function shouldCheckContainsFromRawChildren(): void {
        var child: Sprite = new Sprite();
        var child1: Sprite = new Sprite();
        var child2: Sprite = new Sprite();

        _container.addChildAt(child2, 0);
        _container.addChildAt(child, 0);

        assertTrue(_container.contains(child));
        assertFalse(_container.contains(child1));
    }

    [Test]
    public function shouldSwapChildrenOnRawChildren(): void {
        var child: Sprite = new Sprite();
        var child1: Sprite = new Sprite();
        var child2: Sprite = new Sprite();

        _container.addChildAt(child2, 0);
        _container.addChildAt(child, 1);
        _container.addChildAt(child1, 2);

        _container.swapChildren(child, child2);
        assertEquals(child, _container.rawChildContainer.getChildAt(0));
        assertEquals(child2, _container.rawChildContainer.getChildAt(1));
    }

    [Test]
    public function shouldSwapChildrenAtOnRawChildren(): void {
        var child: Sprite = new Sprite();
        var child1: Sprite = new Sprite();
        var child2: Sprite = new Sprite();

        _container.addChildAt(child2, 0);
        _container.addChildAt(child, 1);
        _container.addChildAt(child1, 2);

        _container.swapChildrenAt(0, 1);
        assertEquals(child, _container.rawChildContainer.getChildAt(0))
        assertEquals(child2, _container.rawChildContainer.getChildAt(1))
    }

    [Test]
    public function shouldAddChildToRawChildren(): void {
        assertEquals(1, _container.rawNumChildren);

        _container.addRawChild(new Sprite());
        assertEquals(2, _container.rawNumChildren);
    }

    [Test]
    public function shouldAddChildAtToRawChildren(): void {
        assertEquals(1, _container.rawNumChildren);

        _container.addRawChildAt(new Sprite(), 0);
        assertEquals(2, _container.rawNumChildren);
    }

    [Test]
    public function shouldRemoveChildToRawChildren(): void {
        assertEquals(1, _container.rawNumChildren);

        var child: Sprite = new Sprite();
        var child1: Sprite = new Sprite();

        _container.addRawChildAt(child, 0);
        _container.addRawChildAt(child1, 0);
        assertEquals(3, _container.rawNumChildren);

        _container.removeRawChild(child);
        assertEquals(2, _container.rawNumChildren);
    }

    [Test]
    public function shouldRemoveChildAtToRawChildren(): void {
        assertEquals(1, _container.rawNumChildren);

        var child: Sprite = new Sprite();
        var child1: Sprite = new Sprite();

        _container.addRawChildAt(child, 0);
        _container.addRawChildAt(child1, 0);
        assertEquals(3, _container.rawNumChildren);

        _container.removeRawChildAt(0);
        assertEquals(2, _container.rawNumChildren);
    }

    [Test]
    public function shouldGetChildAtToRawChildren(): void {
        assertEquals(1, _container.rawNumChildren);

        var child: Sprite = new Sprite();
        var child1: Sprite = new Sprite();

        _container.addRawChildAt(child, 0);
        _container.addRawChildAt(child1, 0);
        assertEquals(3, _container.rawNumChildren);

        assertEquals(child, _container.getRawChildAt(1));
        assertEquals(child1, _container.getRawChildAt(0));

    }

    [Test]
    public function shouldHaveContainsToRawChildren(): void {
        assertEquals(1, _container.rawNumChildren);

        var child: Sprite = new Sprite();
        var child1: Sprite = new Sprite();

        _container.addRawChildAt(child, 0);
        assertEquals(2, _container.rawNumChildren);

        assertTrue(_container.rawContains(child));
        assertFalse(_container.rawContains(child1));

    }

    [Test(async)]
    public function shouldDispatchContainerChildrenChangeEventWhenAddingAChild(): void {
        _container.addEventListener(ContainerEvent.RAW_CHILDREN_CHANGE, Async.asyncHandler(this, function(ce: ContainerEvent, o: Object): void {
            assertTrue(true);
            assertEquals(child, ce.child);
            assertEquals(_container, ce.container);
        }, 100));

        var child: Sprite = new Sprite();
        _container.addChild(child);
    }

    [Test(async)]
    public function shouldDispatchConatinerChildrenChangeEventWhenAddingChildAt(): void {
        _container.addEventListener(ContainerEvent.RAW_CHILDREN_CHANGE, Async.asyncHandler(this, function(ce: ContainerEvent, o: Object): void {
            assertTrue(true);
            assertEquals(child, ce.child);
            assertEquals(_container, ce.container);
        }, 100));

        var child: Sprite = new Sprite();
        _container.addChildAt(child, 0);

    }

    [Test(async)]
    public function shouldDispatchConatinerChildrenChangeEventWhenRemovingChild(): void {
        _container.addEventListener(ContainerEvent.RAW_CHILDREN_CHANGE, Async.asyncHandler(this, function(ce: ContainerEvent, o: Object): void {
            assertTrue(true);
            assertEquals(child, ce.child);
            assertEquals(_container, ce.container);
        }, 100));

        var child: Sprite = new Sprite();
        _container.rawChildContainer.addChild(child);
        _container.removeChild(child);
    }

    [Test(async)]
    public function shouldDispatchConatinerChildrenChangeEventWhenRemovingChildAt(): void {
        _container.addEventListener(ContainerEvent.RAW_CHILDREN_CHANGE, Async.asyncHandler(this, function(ce: ContainerEvent, o: Object): void {
            assertTrue(true);
            assertEquals(child, ce.child);
            assertEquals(_container, ce.container);
        }, 100));

        var child: Sprite = new Sprite();
        _container.rawChildContainer.addChild(child);
        _container.removeChildAt(0);
    }

    [Test(async)]
    public function shouldDispatchConatinerChildrenChangeEventWhenSwappingChildren(): void {
        _container.addEventListener(ContainerEvent.RAW_CHILDREN_CHANGE, Async.asyncHandler(this, function(ce: ContainerEvent, o: Object): void {
            assertTrue(true);
            assertNull(ce.child);
            assertEquals(_container, ce.container);
        }, 100));

        var child: Sprite = new Sprite();
        var child2: Sprite = new Sprite();
        _container.rawChildContainer.addChild(child);
        _container.rawChildContainer.addChild(child2);
        _container.swapChildren(child, child2);
    }

    [Test(async)]
    public function shouldDispatchConatinerChildrenChangeEventWhenSwappingChildrenAt(): void {
        _container.addEventListener(ContainerEvent.RAW_CHILDREN_CHANGE, Async.asyncHandler(this, function(ce: ContainerEvent, o: Object): void {
            assertTrue(true);
            assertNull(ce.child);
            assertEquals(_container, ce.container);
        }, 100));

        var child: Sprite = new Sprite();
        var child2: Sprite = new Sprite();
        _container.rawChildContainer.addChild(child);
        _container.rawChildContainer.addChild(child2);
        _container.swapChildrenAt(0, 1);
    }

    [Test(async)]
    public function shouldDispatchRecalculateBoundsEventIfToldToDoSo(): void {
        _container.addEventListener(ContainerEvent.RECALCULATE_BOUNDS, Async.asyncHandler(this, function(ce: ContainerEvent, o: Object): void {
            assertTrue(true);
            assertNull(ce.child);
            assertEquals(_container, ce.container);
        }, 100));

        var child: Sprite = new Sprite();
        var child2: Sprite = new Sprite();
        _container.rawChildContainer.addChild(child);
        _container.rawChildContainer.addChild(child2);

        _container.recalculateBounds();
    }

}
}
